package com.liit.util;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.util.Assert;

import cn.liit.weixin.core.basic.accesstoken.AccessTokenSupport;
import cn.liit.weixin.templatemsg.utils.MsgUtil;

import com.liit.entity.CommodityFormMap;
import com.liit.entity.DictFormMap;
import com.liit.entity.IntegralDetailFormMap;
import com.liit.entity.IntegralDto;
import com.liit.entity.OrgInfoFormMap;
import com.liit.entity.PartyAttendFormMap;
import com.liit.entity.PartyFormMap;
import com.liit.entity.WeixinUserFormMap;
import com.liit.exception.SystemException;
import com.liit.mapper.CommodityMapper;
import com.liit.mapper.OrgInfoMapper;
import com.liit.mapper.PartyAttendMapper;
import com.liit.mapper.PartyMapper;
import com.liit.mapper.WeixinUserMapper;
import com.liit.spring.SpringUtils;

/**
 * @author dingweibo
 * @Title: IntegralUtils.java
 * @Description: 积分相关
 * @date 2016年4月4日
 */
public class IntegralUtils {

	public static final int TYPE_COMPLETE_USERINFO = 0;// 完善个人资料
	public static final int TYPE_PARTY_COMMENT = 1;// 活动评价
	public static final int TYPE_PARTY_CHECKIN = 2;// 活动签到
	public static final int TYPE_COMMODITY_EXCHANGE = 3;// 商品兑换
	public static final int TYPE_PARTY_PASS = 4;// 发布活动

	public static final ThreadLocal<Object> current = new ThreadLocal<Object>();

	private static final IntegralUtils iUtils = new IntegralUtils();

	private IntegralUtils() {
	}

	public static IntegralUtils getInstance() {
		return iUtils;
	}

	/***
	 * 完善个人资料
	 * 
	 * @param openid
	 */
	public void completeUserinfo(String openid) {
		IntegralDto dto = new IntegralDto();
		dto.setType(TYPE_COMPLETE_USERINFO);
		dto.setOpenid(openid);
		addIntegral(dto);
	}

	/**
	 * 活动评价
	 * 
	 * @param openid
	 * @param partyId
	 */
	public void partyComment(String openid, Integer partyId) {
		IntegralDto dto = new IntegralDto();
		dto.setType(TYPE_PARTY_COMMENT);
		dto.setOpenid(openid);
		dto.setPartyId(partyId);
		addIntegral(dto);
	}

	/**
	 * 活动签到
	 * 
	 * @param openid
	 * @param partyId
	 */
	public void partyCheckin(String openid, Integer partyId) {
		IntegralDto dto = new IntegralDto();
		dto.setType(TYPE_PARTY_CHECKIN);
		dto.setOpenid(openid);
		dto.setPartyId(partyId);
		addIntegral(dto);
	}

	/**
	 * 商品兑换
	 * 
	 * @param openid
	 * @param commodityId
	 */
	public void commodityExchange(String openid, Integer commodityId) {
		IntegralDto dto = new IntegralDto();
		dto.setType(TYPE_COMMODITY_EXCHANGE);
		dto.setOpenid(openid);
		dto.setCommodityId(commodityId);
		addIntegral(dto);
	}

	/**
	 * 活动通过
	 * 
	 * @param partyId
	 */
	public void partyPass(Integer partyId) {
		IntegralDto dto = new IntegralDto();
		dto.setType(TYPE_PARTY_PASS);
		dto.setPartyId(partyId);
		addIntegral(dto);
	}

	/**
	 * 添加积分
	 * 
	 * @param dto
	 */
	@SuppressWarnings("deprecation")
	public void addIntegral(IntegralDto dto) {
		try {

			Assert.notNull(dto, "dto is null");
			Assert.notNull(dto.getType(), "type is null");

			current.set(new Timestamp(System.currentTimeMillis()));

			if (TYPE_COMPLETE_USERINFO == dto.getType()) {// 完善个人资料

				Assert.hasText(dto.getOpenid(), "openid is null");

				// 添加个人积分
				DictFormMap dict = DictUtils.getFirstDict("INTEGRAL_A");
				addPersonalIntegral(new Integral(dict.getInt("value"), dto.getOpenid(), null, null, dict.getStr("label"), null));

			} else if (TYPE_PARTY_COMMENT == dto.getType()) {// 活动评价

				Assert.hasText(dto.getOpenid(), "openid is null");
				Assert.notNull(dto.getPartyId(), "partyId is null");

				OrgInfoMapper mapper = SpringUtils.getBean(OrgInfoMapper.class);

				// 查询活动信息
				PartyFormMap partyRecord = mapper.findbyFrist("id", dto.getPartyId().toString(), PartyFormMap.class);

				// 查询活动评价信息
				PartyAttendFormMap partyAttendRecord = new PartyAttendFormMap();
				partyAttendRecord.put("openid", dto.getOpenid());
				partyAttendRecord.put("partyId", dto.getPartyId());
				partyAttendRecord.put("status", Common.COMMON_YES);
				partyAttendRecord = mapper.findByNames(partyAttendRecord).get(0);// 用户评价信息

				Assert.state(partyAttendRecord.getInt("starLevel") > 0, "starLevel comment less then 0");

				// 评价时间超过活动结束7天的
				int i7 = DateUtils.add(partyRecord.getTimestamp("endTime"), Calendar.DAY_OF_MONTH, 7).compareTo(new Date()) == -1 ? -1 : 0;
				Integral entity = null;
				String description = "活动评价:" + partyRecord.getStr("subject");
				String remark = "partyId:" + dto.getPartyId();

				// 有文字和星级评价的
				if (StringUtils.isNotBlank(partyAttendRecord.getStr("comment"))) {
					// 文字内容未超过10
					int i10 = StringUtils.trimToEmpty(partyAttendRecord.getStr("comment")).length() > 10 ? 0 : -1;
					int num = DictUtils.getFirstDictValue("INTEGRAL_B") + i7 + DictUtils.getFirstDictValue("INTEGRAL_C") + i10 + i7;

					entity = new Integral(num, dto.getOpenid(), dto.getPartyId(), partyRecord.getInt("orgInfoId"), description, remark);

					// 添加个人积分
					addPersonalIntegral(entity);

				} else {// 只有星级评价的

					int num = DictUtils.getFirstDictValue("INTEGRAL_B") + i7;
					entity = new Integral(num, dto.getOpenid(), dto.getPartyId(), partyRecord.getInt("orgInfoId"), description, remark);

					// 添加个人积分
					addPersonalIntegral(entity);
				}

				// 添加组织积分
				entity.num = DictUtils.getFirstDictValue("INTEGRAL_H") * partyAttendRecord.getInt("starLevel");
				addOrgIntegral(entity);

				// 添加活动积分
				addPartyIntegral(entity);

			} else if (TYPE_PARTY_CHECKIN == dto.getType()) {// 签到

				Assert.hasText(dto.getOpenid(), "openid is null");
				Assert.notNull(dto.getPartyId(), "partyId is null");

				PartyAttendMapper mapper = SpringUtils.getBean(PartyAttendMapper.class);

				// 查询活动信息
				PartyFormMap partyRecord = mapper.findbyFrist("id", dto.getPartyId().toString(), PartyFormMap.class);

				DictFormMap dict = DictUtils.getFirstDict("INTEGRAL_F");
				int num = dict.getInt("value");
				String description = "活动签到:" + partyRecord.getStr("subject");
				String remark = "partyId:" + dto.getPartyId();

				Integral entity = new Integral(num, dto.getOpenid(), dto.getPartyId(), partyRecord.getInt("orgInfoId"), description, remark);
				// 添加个人积分
				addPersonalIntegral(entity);

				// 添加机构积分
				entity.num = DictUtils.getFirstDictValue("INTEGRAL_I");
				addOrgIntegral(entity);
				// 添加活动积分
				addPartyIntegral(entity);

				// 查询活动签到信息
				PartyAttendFormMap partyAttendRecord = new PartyAttendFormMap();
				partyAttendRecord.put("partyId", dto.getPartyId());
				// 活动审批通过且参与活动人数大于5时
				if (partyRecord.getInt("status") == Common.ORG_STATUS_PASS && mapper.findByNames(partyAttendRecord).size() == 6) {
					entity.num = DictUtils.getFirstDictValue("INTEGRAL_G");
					entity.description = DictUtils.getFirstDictLabel("INTEGRAL_G") + ":" + partyRecord.getStr("subject");
					addOrgIntegral(entity);

					// 添加活动积分
					addPartyIntegral(entity);
				}

			} else if (TYPE_COMMODITY_EXCHANGE == dto.getType()) {// 兑换商品

				Assert.hasText(dto.getOpenid(), "openid is null");
				Assert.notNull(dto.getCommodityId(), "commodityId is null");

				CommodityMapper mapper = SpringUtils.getBean(CommodityMapper.class);

				// 商品信息
				CommodityFormMap commodityRecord = mapper.findbyFrist("id", dto.getCommodityId().toString(), CommodityFormMap.class);
				// 微信用户
				WeixinUserFormMap weixinUser = mapper.findbyFrist("openid", dto.getOpenid(), WeixinUserFormMap.class);

				// 判断用户积分是否足够
				Assert.isTrue(weixinUser.getInt("integral") > commodityRecord.getInt("integralPrice"), "user integral less then integralPrice");

				int num = 0 - commodityRecord.getInt("integralPrice");
				String description = "兑换礼品:" + commodityRecord.getStr("name");
				String remark = "commodityId:" + dto.getCommodityId();

				// 抵扣个人积分
				addPersonalIntegral(new Integral(num, dto.getOpenid(), null, null, description, remark));
				// 推送微信提醒消息
				String msg = "尊敬的用户:" + weixinUser.getStr("nickname") + ",您已成功兑换礼品[" + commodityRecord.getStr("name") + "],本次使用" + commodityRecord.getInt("integralPrice") + "积分.\\n";
				MsgUtil.sendTemplateMsg(AccessTokenSupport.getAccess_token(), dto.getOpenid(), "", PropertiesUtils.findPropertiesKey("templateid.integral"), msg, new String[] {
						Integer.toString(num), Common.format((Date) current.get(), "yyyy-MM-dd HH:mm:ss") }, "");

			} else if (TYPE_PARTY_PASS == dto.getType()) {// 活动发布

				Assert.notNull(dto.getPartyId(), "partyId is null");

				WeixinUserMapper mapper = SpringUtils.getBean(WeixinUserMapper.class);
				// 活动信息
				PartyFormMap party = mapper.findbyFrist("id", dto.getPartyId().toString(), PartyFormMap.class);
				Assert.notNull(party, "party info is null");

				int num = DictUtils.getFirstDictValue("INTEGRAL_J");
				String description = "发布活动:" + party.getStr("subject");
				Integral entity = new Integral(num, party.getStr("openid"), dto.getPartyId(), party.getInt("orgInfoId"), description, null);

				// 添加机构积分
				addOrgIntegral(entity);
				// 添加活动积分
				addPartyIntegral(entity);
			}
		} catch (Exception e) {
			throw new SystemException(e);
		} finally {
			current.remove();
		}
	}

	/**
	 * 添加个人积分
	 * 
	 * @param entity
	 * @throws Exception
	 */
	private void addPersonalIntegral(Integral entity) throws Exception {

		WeixinUserMapper mapper = SpringUtils.getBean(WeixinUserMapper.class);

		// 添加个人积分
		WeixinUserFormMap record = mapper.findbyFrist("openid", entity.openid, WeixinUserFormMap.class);
		WeixinUserFormMap wxUser = new WeixinUserFormMap();
		wxUser.put("id", record.getInt("id"));
		wxUser.put("integral", record.getInt("integral") + entity.num);
		mapper.editEntity(wxUser);

		// 记录历史
		IntegralDetailFormMap history = new IntegralDetailFormMap();
		history.put("integral", entity.num);
		history.put("balance", wxUser.getInt("integral"));
		history.put("openid", entity.openid);
		history.put("orgInfoId", entity.orgInfoId);
		history.put("description", entity.description);
		history.put("remark", entity.remark);
		history.put("type", 0);// 个人
		history.put("createTime", current.get());
		mapper.addEntity(history);
	}

	/**
	 * 添加机构积分
	 * 
	 * @param entity
	 * @throws Exception
	 */
	private void addOrgIntegral(Integral entity) throws Exception {

		OrgInfoMapper mapper = SpringUtils.getBean(OrgInfoMapper.class);

		// 添加机构积分
		OrgInfoFormMap record = mapper.findbyFrist("id", entity.orgInfoId.toString(), OrgInfoFormMap.class);
		OrgInfoFormMap orgInfo = new OrgInfoFormMap();
		orgInfo.put("id", record.getInt("id"));
		orgInfo.put("integral", record.getInt("integral") + entity.num);
		mapper.editEntity(orgInfo);

		// 记录历史
		IntegralDetailFormMap history = new IntegralDetailFormMap();
		history.put("integral", entity.num);
		history.put("balance", orgInfo.getInt("integral"));
		history.put("openid", entity.openid);
		history.put("orgInfoId", entity.orgInfoId);
		history.put("description", entity.description);
		history.put("remark", entity.remark);
		history.put("type", 1);// 机构
		history.put("createTime", current.get());
		mapper.addEntity(history);
	}

	/**
	 * 活动积分
	 * 
	 * @param entity
	 * @throws Exception
	 */
	private void addPartyIntegral(Integral entity) throws Exception {

		PartyMapper mapper = SpringUtils.getBean(PartyMapper.class);

		// 活动信息
		PartyFormMap partyRecord = mapper.findbyFrist("id", entity.partyId.toString(), PartyFormMap.class);
		// 添加活动积分
		PartyFormMap party = new PartyFormMap();
		party.put("id", entity.partyId);
		party.put("integral", partyRecord.getInt("integral") + entity.num);
		mapper.editEntity(party);
	}

	private class Integral {
		/**
		 * 个人积分增量
		 */
		Integer num;

		/**
		 * openId
		 */
		String openid;

		/**
		 * 活动ID
		 */
		Integer partyId;

		/**
		 * 机构ID
		 */
		Integer orgInfoId;

		/**
		 * 描述
		 */
		String description;

		/**
		 * 描述
		 */
		String remark;

		/**
		 * @param num
		 * @param openid
		 * @param partyId
		 * @param orgInfoId
		 * @param description
		 * @param remark
		 */
		private Integral(Integer num, String openid, Integer partyId, Integer orgInfoId, String description, String remark) {
			super();
			this.num = num;
			this.openid = openid;
			this.partyId = partyId;
			this.orgInfoId = orgInfoId;
			this.description = description;
			this.remark = remark;
		}
	}
}
